package ml.coursedesign.common.util;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.Data;
import ml.coursedesign.entity.Student;
import org.springframework.stereotype.Component;

import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Data
@Component
public class JWTUtils {
    
    private String secret = "abcdefg1234567";
    
    private long expire = 3600000;
    
    private String header = "token";
    
    /**
     * 生成token令牌
     *
     * @param username
     * @param role
     * @return
     */
    public String createToken(String username, String role) {
        Map<String, Object> claims = new HashMap<>();
        claims.put("username", username);
        claims.put("role", role);
        return createToken(claims);
    }
    
    public String createToken(String username, String role, Integer id) {
        Map<String, Object> claims = new HashMap<>();
        System.err.println(username);
        claims.put("username", username);
        claims.put("role", role);
        claims.put("Id", id);
        return createToken(claims);
    }
    
    
    /**
     * 从token中获得用户名
     *
     * @param token
     * @return
     */
    public String getUsernameFromToken(String token) {
        String username;
        try {
            Claims claims = getClaimsFromToken(token);
            
            username = claims.get("username", String.class);
            
        } catch (Exception e) {
            username = null;
        }
        return username;
    }
    
    /**
     * 获取id
     *
     * @param token
     * @return
     */
    public String getUserIdFromToken(String token) {
        String id;
        try {
            Claims claims = getClaimsFromToken(token);
            System.out.println("claims" + claims);
            id = claims.get("Id", String.class);
            
        } catch (Exception e) {
            id = null;
        }
        return id;
    }
    
    /**
     * 从token中获得用户名
     *
     * @param token
     * @return
     */
    public String getRoleFromToken(String token) {
        String role;
        try {
            Claims claims = getClaimsFromToken(token);
            System.out.println("claims" + claims);
            role = claims.get("role", String.class);
            // System.out.println("当前用户权限：" + role);
        } catch (Exception e) {
            role = null;
        }
        return role;
    }
    
    /**
     * 判断令牌是否过期
     *
     * @param token
     * @return
     */
    public Boolean isTokenExpired(String token) {
        try {
            Claims claims = getClaimsFromToken(token);
            
            Date expiration = claims.getExpiration();
            return expiration.before(new Date());
        } catch (Exception e) {
            return false;
        }
    }
    
    /**
     * 刷新令牌
     *
     * @param token
     * @return
     */
    public String refreshToken(String token) {
        String refreshToken;
        try {
            Claims claims = getClaimsFromToken(token);
            
            refreshToken = createToken(claims);
            
        } catch (Exception e) {
            refreshToken = null;
        }
        return refreshToken;
    }
    
    /**
     * 验证令牌是否有效
     *
     * @param token
     * @param student
     * @return
     */
    public Boolean validateToken(String token, Student student) {
        String username = getUsernameFromToken(token);
        return (username.equals(student.getUsername()) && !isTokenExpired(token));
    }
    
    
    /**
     * 从令牌中获取数据声明,
     *
     * @param token
     * @return
     */
    private Claims getClaimsFromToken(String token) {
        Claims claims;
        try {
            claims = Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
        } catch (Exception e) {
            claims = null;
        }
        return claims;
    }
    
    
    /***
     * 从claims生成令牌
     * @param claims
     * @return
     */
    public String createToken(Map<String, Object> claims) {
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.SECOND, 60);
        return Jwts.builder()
                .setExpiration(instance.getTime())
                .setClaims(claims)
                .signWith(SignatureAlgorithm.HS512, secret)
                .compact();
    }
    
}

